import LayVmodelBase from "./LayVmodelBase.js"
import { logger, tools, runtime } from "./tools.js";


class LaySliderVmodel extends LayVmodelBase {
    config = null;
    constructor(elem, config) {
        super(elem);
        this.config = config || {};
        this.config.elem = this.element;
    }

    viewModelInit() {
        this.vm.value = ko.observable();
        this.vm.begin = ko.observable();
        this.vm.end = ko.observable();
        this.vm.range = ko.observableArray([]);
    }

    onDisabledChange(disabled) {
        let dyConfig = {};
        let tis = this;
        if (disabled === this.vm.disabled()) return;

        Object.assign(dyConfig, this.config);
        for (let key in dyConfig) {
            let fn = dyConfig[key];
            if (typeof fn === "function") {
                dyConfig[key] = tis.config[key];
            }
        }

        dyConfig.disabled = disabled;
        dyConfig.elem = this.element;
        dyConfig.value = this.config.range ? [this.vm.begin(), this.vm.end()] : this.vm.value();
        let slider = tools.laymod('slider');
        //$(this.element).empty();
        this.instance = slider.render(dyConfig);
    }

    init() {
        if (!super.init()) return;
        let tis = this;
        let vm = this.vm;
        let range = tis.config.range;

        var lastValue = [];
        var lastCmpValue = [];
        //避免覆盖原有事件
        var innerChange = this.config.change;

        if (this.config.value == void 0) {
            this.config.value = vm.value();
        }

        //范围选择
        if (range) {
            vm.begin?.subscribe((newValue) => {
                if (newValue !== lastValue[0]) {
                    tis.instance.setValue(newValue, 0);
                    lastValue[0] = newValue;
                }
            }, null, "change");

            vm.end?.subscribe((newValue) => {
                if (newValue !== lastValue[1]) {
                    tis.instance.setValue(newValue, 1);
                    lastValue[1] = newValue;
                }
            }, null, "change");

            vm.range?.subscribe((newValue) => {
                let begin = newValue[0];
                let end = newValue[1];

                if (begin !== lastValue[0]) {
                    tis.instance.setValue(begin, 0);
                    lastValue[0] = begin;
                }
                if (end !== lastValue[1]) {
                    tis.instance.setValue(end, 1);
                    lastValue[1] = end;
                }
            }, null, "change");

            this.config.change = function (value) {
                let vmValue = vm.value();
                if(vm.range && (value[0] !== lastCmpValue[0] || value[1] !== lastCmpValue[1])){
                    lastCmpValue = value.slice(0);
                    vm.range([value[0], value[1]]);
                    innerChange && innerChange.call(this, ...arguments);                    
                }

                if (value[0] !== lastCmpValue[0]) {
                    lastCmpValue[0] = value[0];                    
                    vm.begin(value[0]);
                    innerChange && innerChange.call(this, ...arguments);
                }

                if (value[1] !== lastCmpValue[1]) {
                    lastCmpValue[1] = value[1];
                    vm.end(value[1]);
                    innerChange && innerChange.call(this, ...arguments);
                }
            };

            if (vm.begin() && vm.end()) {
                this.config.value = [vm.begin(), vm.end()];                
            }
            else if (vm.range()) {
                this.config.value = vm.range();
            }

            lastValue[0] = lastCmpValue[0] = (this.config.value && this.config.value[0]) || 0;
            lastValue[1] = lastCmpValue[1] = (this.config.value && this.config.value[1]) || 0;

            vm.begin && vm.begin(lastValue[0]);
            vm.end && vm.end(lastValue[1]);
            vm.range && vm.range([lastValue[0], lastValue[1]]);
        }

        //非范围选择
        else {
            vm.value?.subscribe((newValue) => {
                let vmValue = vm.value();
                if (newValue === lastValue) return;
                tis.instance.setValue(newValue);
                lastValue = newValue;
            }, null, "change");

            this.config.change = function (value) {
                let vmValue = vm.value();

                if (value === vmValue) return;
                vm.value(value);

                innerChange && innerChange.call(this, ...arguments);
            };
            lastValue = lastCmpValue = this.config.value || 0;
            vm.value(lastValue);
        }

        let slider = tools.laymod('slider');
        this.instance = slider.render(this.config);
        this.inited = true;
    }
}

export default LaySliderVmodel;